package com.noob.assessment.service.impl;

import com.noob.assessment.domain.bo.FileUpdateBO;
import com.noob.assessment.domain.dto.FileUpdateResultDTO;
import com.noob.assessment.domain.dto.LockResultDTO;
import com.noob.assessment.domain.po.FileInfoPO;
import com.noob.assessment.manage.storage.StorageManager;
import com.noob.assessment.service.FileInfoService;
import com.noob.assessment.service.FileLockService;
import com.noob.assessment.service.FileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author: zhengwq
 * datetime: 2020-04-20 21:06
 * description: 文件服务 接口实现
 */
@Service
public class FileServiceImpl implements FileService {

    /**
     * 文件信息服务
     */
    @Autowired
    private FileInfoService fileInfoService;

    /**
     * 文件锁服务
     */
    @Autowired
    private FileLockService fileLockService;

    /**
     * 文件存储管理器
     */
    @Autowired
    private StorageManager storageManager;

    /**
     * 创建文件
     *
     * @param fileName    文件名
     * @param fileContent 文件内容
     * @return 创建文件结果 成功：true 失败：false'
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createFile(String fileName, String fileContent) {
        // 事务
        // 更新文件信息表
        boolean saveFileInfo = fileInfoService.saveOrUpdate(new FileInfoPO(fileName));
        // 更新磁盘文件
        boolean saveFile = storageManager.saveOrUpdateFile(fileName, fileContent);
        return saveFileInfo && saveFile;
    }

    /**
     * 获取文件内容
     *
     * @param fileName 文件名
     * @return 文件内容
     */
    @Override
    public String getFileContent(String fileName) {
        return storageManager.readFile(fileName);
    }

    /**
     * 更新文件
     * 一个原则：只有当前用户持有该文件的锁 才允许更新该文件
     * 更新失败与否都会返回当前文件锁的信息 用于提示用户
     * @return 文件更新结果DTO
     */
    @Override
    public FileUpdateResultDTO updateFile(FileUpdateBO fileUpdateBO) {
        Integer fileId = fileUpdateBO.getFileId();
        String userId = fileUpdateBO.getUserId();
        String fileContent = fileUpdateBO.getFileContent();
        String fileName = fileUpdateBO.getFileName();

        // 尝试获取文件锁
        LockResultDTO lockResultDTO = fileLockService.tryLockFile(fileId, userId);

        // 构建文件更新结果对象
        FileUpdateResultDTO fileUpdateResultDTO = FileUpdateResultDTO.builder()
                // 记录当前锁的情况
                .holder(lockResultDTO.getHolder())
                .ttl(lockResultDTO.getTtl())
                // 先把文件更新结果设置为false
                .result(false)
                .build();

        // 成功获得锁
        if (lockResultDTO.getResult()) {
            // 更新磁盘文件
            boolean result = storageManager.saveOrUpdateFile(fileName, fileContent);
            // 设置磁盘文件更新结果
            fileUpdateResultDTO.setResult(result);
        }

        return fileUpdateResultDTO;
    }

}
